# -*- coding: utf-8 -*-
# $Id: commandline.py 27 2009-02-15 19:46:27Z gkuznets $

# Copyright 2008, 2009 Grigoriy Kuznetsov (gkuznets@yandex.ru)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

from PyQt4 import QtCore, QtGui
from PyQt4.QtCore import QString, Qt, QTimer, SIGNAL
from PyQt4.QtGui import QFont, QLabel, QUndoStack, QUndoCommand
from addbatchdialog import AddBatchDialog
from core.batch import *
from checkup import Checkup
checkup = Checkup.instance()
from undo import *

from commandparser import CommandParser

class CommandLine(QLabel):
    """Командная строка"""
    
    displaying_error_ = True
    
    def __init__(self):
        QLabel.__init__(self)
        self.parser = CommandParser()
        self.connect(self.parser, SIGNAL("error"), self.error)
        # Полезные команды
        self.connect(self.parser, SIGNAL("help"), self.help)
    #    self.connect(self.parser, SIGNAL("undo"), self.undo)
        self.connect(self.parser, SIGNAL("highlight"), self.highlight)
    #    self.connect(self.parser, SIGNAL("sbtg"), self.sbtg)
    #    self.connect(self.parser, SIGNAL("bb"), self.bb)
        self.connect(self.parser, SIGNAL("add"), self.add)
        self.connect(self.parser, SIGNAL("mark"), self.mark)
        self.connect(self.parser, SIGNAL("mistake"), self.mistake)
    #    self.connect(self.parser, SIGNAL("second"), self.second)
        # undo stack
        self.undo_stack_ = QtGui.QUndoStack()
        self.setText(QString(u"Готово"))
        # Таймер отмены команды
        self.clear_command_timer = QTimer(self)
        self.clear_command_timer.setSingleShot(True)
        self.clear_command_timer.setInterval(3000)
        self.connect(self.clear_command_timer, QtCore.SIGNAL("timeout()"), self.clear)
    
    def start(self):
        self.connect(self.parser, SIGNAL("undo"), self.undo)
        self.connect(self.parser, SIGNAL("sbtg"), self.sbtg)
        self.connect(self.parser, SIGNAL("bb"), self.bb)
        self.connect(self.parser, SIGNAL("second"), self.second)
    
    def error(self, message):
        print message
        self.setText(QString(u"<font color=\"red\">%1</font>").arg(message))
        self.displaying_error_ = True
    
    def keyPressEvent(self, key_event):
        if key_event.key() == Qt.Key_Escape:
            self.clear()
            return
        elif key_event.key() == Qt.Key_F12:
            self.emit(SIGNAL("toggle_fullscreen"))
            self.clear()
            return
        if self.displaying_error_ == True:
            self.clear()
            self.displaying_error_ = False
        self.setText(QString(u"%1").arg(self.text()+key_event.text()))
        self.parser(self.text())
        self.clear_command_timer.start()
  
    def help(self):
        # Строка сообщения об используемых командах
        help_message = u"""Доступны следующие команды:
        №№# \t\t послать пачку №№ на проверку задачи #
        №№<пробел> \t забрать пачку с проверки
        а \t\t добавить пачку работ
        f№№ \t\t пометить/снять помету с пачки №№
        u \t\t отменить последнее действие
        second \t\t начать вторую проверку
        <esc> \t\t удаляет текущие символы команды
        h \t\t помощь(выводит это сообщение)
        """
        #self.releaseKeyboard()
        QtGui.QMessageBox.information(self, QString(u"Список доступных команд"), 
                                      help_message, QtGui.QMessageBox.Ok)
        #self.grabKeyboard()
        self.setText(QString())
    
    def undo(self):
        if self.undo_stack_.canUndo():
            self.undo_stack_.undo()
        self.clear()
        self.emit(SIGNAL("update"))
    
    def highlight(self, bno):
        b = Batch.find(bno)
        if b is not None:
            b.select()
            self.emit(SIGNAL("update_properties"))
    
    def sbtg(self, bno, pno):
        """Посылает пачку bno на проверку задачи pno"""
        if not 0 <= pno < checkup.problems_count:
            self.error(u"Неверный номер задачи (%d)" % pno+1)
            return
        batch = Batch.find(bno)
        if batch:
            if batch.group:
                self.error(u"Данная пачка (%s) уже находится на проверке задачи %d" % (batch.name(), batch.group.index+1))
                return
            batch.sendToProblem(pno)
            self.emit(SIGNAL("ChangesEvent"))
            self.emit(SIGNAL("groupChanged"), pno)
            self.emit(SIGNAL("update"))
            self.clear()
            # push undo
            self.undo_stack_.push(SBTG_UC(bno, pno))
        else:
            self.error(u"Неверный номер пачки (%d)" % bno)
  
    def bb(self, bno):
        """Забирает пачку с проверки"""
        batch = Batch.find(bno)
        if batch:
            if batch.group is None:
                self.error(u"Пачка (%d) не находится на проверке" % bno)
            else:
                pindex = batch.group.index
                batch.takeBack()
                self.clear()
                self.emit(SIGNAL("ChangesEvent"))
                self.emit(SIGNAL("groupChanged"), pindex)
                self.emit(SIGNAL("update"))
        else:
            self.error(u"Неверный номер пачки (%d)" % bno)
    
    def add(self):
        """Запускает диалог добавления новой пвчки"""
        dialog = AddBatchDialog()
        self.releaseKeyboard()
        dialog.exec_()
        self.grabKeyboard()
        self.clear()
        self.emit(SIGNAL("ChangesEvent"))
        self.emit(SIGNAL("update"))
    
    def mark(self, bno):
        batch = Batch.find(bno)
        if batch:
            batch.marked = not batch.marked
            self.clear()
            self.emit(SIGNAL("markedChanged"))
            self.emit(SIGNAL("ChangesEvent"))
            self.emit(SIGNAL("update"))
        else:
            self.error(u"Неверный номер пачки (%d)" % bno)
    
    def mistake(self):
        self.clear()
    
    def second(self):
        """Начинает вторую проверку"""
        checkup.nextCheckup()
        self.clear()
        self.emit(SIGNAL("ChangesEvent"))
        for c in range(6):
            self.emit(SIGNAL("groupChanged"), c)
        self.emit(SIGNAL("update"))
